package com.du.quant.service;

import com.du.quant.dto.StockAnalysisDTO;
import com.du.quant.dto.TradingAdviceDTO;
import com.du.quant.entity.TradingAdvice;
import com.du.quant.mapper.TradingAdviceMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class TradingAdviceService {

    @Autowired
    private DeepSeekService deepSeekService;

    @Autowired
    private TradingAdviceMapper tradingAdviceMapper;

    @Transactional
    public TradingAdviceDTO generateAdvice(StockAnalysisDTO analysisDTO) {
        try {
            // 调用大模型分析
            String analysisResult = deepSeekService.analyzeStockTrading(analysisDTO);

            // 解析大模型返回结果
            TradingAdviceDTO adviceDTO = parseAdviceFromAI(analysisResult, analysisDTO);

            // 保存到数据库
//            saveAdviceToDB(analysisDTO.getStockCode(), adviceDTO, analysisResult);

            return adviceDTO;

        } catch (Exception e) {
            log.error("生成交易建议失败: {}", analysisDTO.getStockCode(), e);
            return createErrorAdvice();
        }
    }

    private TradingAdviceDTO parseAdviceFromAI(String aiResponse, StockAnalysisDTO analysisDTO) {
        TradingAdviceDTO advice = new TradingAdviceDTO();

        try {
            // 解析建议类型
            Pattern advicePattern = Pattern.compile("建议：\\s*([加仓|减仓|空仓|持有]+)");
            Matcher adviceMatcher = advicePattern.matcher(aiResponse);
            if (adviceMatcher.find()) {
                String adviceStr = adviceMatcher.group(1);
                advice.setAdviceType(parseAdviceType(adviceStr));
                advice.setAdviceDesc(getAdviceDescription(advice.getAdviceType()));
            } else {
                advice.setAdviceType("HOLD");
                advice.setAdviceDesc("持有");
            }

            // 解析置信度
            Pattern confidencePattern = Pattern.compile("置信度：\\s*(\\d+)");
            Matcher confidenceMatcher = confidencePattern.matcher(aiResponse);
            if (confidenceMatcher.find()) {
                advice.setConfidence(new BigDecimal(confidenceMatcher.group(1)).divide(new BigDecimal("100")));
            } else {
                advice.setConfidence(new BigDecimal("0.7"));
            }

            // 解析理由
            // 匹配从"理由："开始到"目标价格："之前的所有内容
            Pattern pattern = Pattern.compile("理由：\\s*(.*?)\\s*目标价格：", Pattern.DOTALL);
            Matcher matcher = pattern.matcher(aiResponse);

            if (matcher.find()) {
                advice.setReasoning(matcher.group(1));
            } else {
                // 如果没有匹配到，尝试其他可能的模式
                pattern = Pattern.compile("理由：\\s*(.*)", Pattern.DOTALL);
                matcher = pattern.matcher(aiResponse);
                if (matcher.find()) {
                    advice.setReasoning(matcher.group(1));
                } else {
                    advice.setReasoning("未匹配到理由部分");
                }
            }


            // 解析目标价格和止损价格
            advice.setTargetPrice(calculateTargetPrice(
                    analysisDTO.getCurrentPrice(), advice.getAdviceType()));
            advice.setStopLoss(calculateStopLoss(
                    analysisDTO.getCurrentPrice(), advice.getAdviceType()));

        } catch (Exception e) {
            log.warn("解析AI回复失败，使用默认值: {}", e.getMessage());
            advice.setAdviceType("HOLD");
            advice.setAdviceDesc("持有");
            advice.setConfidence(new BigDecimal("0.5"));
            advice.setReasoning("AI分析结果解析失败");
        }

        return advice;
    }

    private String parseAdviceType(String adviceStr) {
        switch (adviceStr) {
            case "加仓": return "BUY";
            case "减仓": return "SELL";
            case "空仓": return "EXIT";
            default: return "HOLD";
        }
    }

    private String getAdviceDescription(String adviceType) {
        switch (adviceType) {
            case "BUY": return "加仓";
            case "SELL": return "减仓";
            case "EXIT": return "空仓";
            default: return "持有";
        }
    }

    private BigDecimal calculateTargetPrice(BigDecimal currentPrice, String adviceType) {
        switch (adviceType) {
            case "BUY": return currentPrice.multiply(new BigDecimal("1.15"));
            case "SELL": return currentPrice.multiply(new BigDecimal("0.95"));
            case "EXIT": return currentPrice.multiply(new BigDecimal("0.90"));
            default: return currentPrice;
        }
    }

    private BigDecimal calculateStopLoss(BigDecimal currentPrice, String adviceType) {
        switch (adviceType) {
            case "BUY": return currentPrice.multiply(new BigDecimal("0.92"));
            case "SELL": return currentPrice.multiply(new BigDecimal("1.05"));
            case "EXIT": return currentPrice.multiply(new BigDecimal("1.02"));
            default: return currentPrice.multiply(new BigDecimal("0.95"));
        }
    }

    @Transactional
    public void saveAdviceToDB(String stockCode, TradingAdviceDTO adviceDTO, String analysisResult) {
        TradingAdvice advice = new TradingAdvice();
        advice.setStockCode(stockCode);
        advice.setAdviceType(adviceDTO.getAdviceType());
        advice.setConfidence(adviceDTO.getConfidence());
        advice.setReasoning(adviceDTO.getReasoning());
        advice.setTargetPrice(adviceDTO.getTargetPrice());
        advice.setStopLoss(adviceDTO.getStopLoss());
        advice.setAnalysisData(analysisResult);
        advice.setCreateTime(LocalDateTime.now());

        tradingAdviceMapper.insert(advice);
    }

    private TradingAdviceDTO createErrorAdvice() {
        TradingAdviceDTO advice = new TradingAdviceDTO();
        advice.setAdviceType("HOLD");
        advice.setAdviceDesc("持有");
        advice.setConfidence(new BigDecimal("0"));
        advice.setReasoning("分析服务暂时不可用");
        return advice;
    }
}